home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / app / lut_funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-16  |  9.8 KB  |  427 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdio.h>
  22. #include <glib.h>
  23.  
  24. #include <glib.h>
  25.  
  26. #include "apptypes.h"
  27.  
  28. #include "appenv.h"
  29. #include "gimplut.h"
  30. #include "gimphistogram.h"
  31.  
  32. #include "libgimp/gimpmath.h"
  33.  
  34. /* ---------- Brightness/Contrast -----------*/
  35.  
  36. typedef struct B_C_struct
  37. {
  38.   double brightness;
  39.   double contrast;
  40. } B_C_struct;
  41.  
  42. static float
  43. brightness_contrast_lut_func(B_C_struct *data,
  44.                  int nchannels, int channel, float value)
  45. {
  46.   float nvalue;
  47.   double power;
  48.  
  49.   /* return the original value for the alpha channel */
  50.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  51.     return value;
  52.  
  53.   /* apply brightness */
  54.   if (data->brightness < 0.0)
  55.     value = value * (1.0 + data->brightness);
  56.   else
  57.     value = value + ((1.0 - value) * data->brightness);
  58.  
  59.   /* apply contrast */
  60.   if (data->contrast < 0.0)
  61.   {
  62.     if (value > 0.5)
  63.       nvalue = 1.0 - value;
  64.     else
  65.       nvalue = value;
  66.     if (nvalue < 0.0)
  67.       nvalue = 0.0;
  68.     nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + data->contrast));
  69.     if (value > 0.5)
  70.       value = 1.0 - nvalue;
  71.     else
  72.       value = nvalue;
  73.   }
  74.   else
  75.   {
  76.     if (value > 0.5)
  77.       nvalue = 1.0 - value;
  78.     else
  79.       nvalue = value;
  80.     if (nvalue < 0.0)
  81.       nvalue = 0.0;
  82.     power = (data->contrast == 1.0) ? 127 : 1.0 / (1.0 - data->contrast);
  83.     nvalue = 0.5 * pow (2.0 * nvalue, power);
  84.     if (value > 0.5)
  85.       value = 1.0 - nvalue;
  86.     else
  87.       value = nvalue;
  88.   }
  89.   return value;
  90. }
  91.  
  92. void
  93. brightness_contrast_lut_setup(GimpLut *lut, double brightness, double contrast,
  94.                   int nchannels)
  95. {
  96.   B_C_struct data;
  97.   data.brightness = brightness;
  98.   data.contrast = contrast;
  99.   gimp_lut_setup(lut,  (GimpLutFunc) brightness_contrast_lut_func,
  100.          (void *) &data, nchannels);
  101. }
  102.  
  103. GimpLut *
  104. brightness_contrast_lut_new(double brightness, double contrast,
  105.                 int nchannels)
  106. {
  107.   GimpLut *lut;
  108.   lut = gimp_lut_new();
  109.   brightness_contrast_lut_setup(lut, brightness, contrast, nchannels);
  110.   return lut;
  111. }
  112.  
  113. /* ---------------- invert ------------------ */
  114.  
  115. static float
  116. invert_lut_func(void *unused,
  117.         int nchannels, int channel, float value)
  118. {
  119.   /* don't invert the alpha channel */
  120.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  121.     return value;
  122.  
  123.   return 1.0 - value;
  124. }
  125.  
  126. void
  127. invert_lut_setup(GimpLut *lut, int nchannels)
  128. {
  129.   gimp_lut_setup_exact(lut,  (GimpLutFunc) invert_lut_func,
  130.                NULL , nchannels);
  131. }
  132.  
  133. GimpLut *
  134. invert_lut_new(int nchannels)
  135. {
  136.   GimpLut *lut;
  137.   lut = gimp_lut_new();
  138.   invert_lut_setup(lut, nchannels);
  139.   return lut;
  140. }
  141.  
  142. /* ---------------- add (or subract)------------------ */
  143.  
  144. static float
  145. add_lut_func(double *ammount,
  146.          int nchannels, int channel, float value)
  147. {
  148.   /* don't change the alpha channel */
  149.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  150.     return value;
  151.  
  152.   return (value + *ammount);
  153. }
  154.  
  155. void
  156. add_lut_setup(GimpLut *lut, double ammount, int nchannels)
  157. {
  158.   gimp_lut_setup(lut,  (GimpLutFunc) add_lut_func,
  159.          (void *) &ammount , nchannels);
  160. }
  161.  
  162. GimpLut *
  163. add_lut_new(double ammount, int nchannels)
  164. {
  165.   GimpLut *lut;
  166.   lut = gimp_lut_new();
  167.   add_lut_setup(lut, ammount, nchannels);
  168.   return lut;
  169. }
  170.  
  171. /* ---------------- intersect (MIN (pixel, value)) ------------------ */
  172.  
  173. static float
  174. intersect_lut_func(double *min,
  175.          int nchannels, int channel, float value)
  176. {
  177.   /* don't change the alpha channel */
  178.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  179.     return value;
  180.  
  181.   return MIN (value, *min);
  182. }
  183.  
  184. void
  185. intersect_lut_setup(GimpLut *lut, double value, int nchannels)
  186. {
  187.   gimp_lut_setup_exact(lut,  (GimpLutFunc) intersect_lut_func,
  188.                (void *) &value , nchannels);
  189. }
  190.  
  191. GimpLut *
  192. intersect_lut_new(double value, int nchannels)
  193. {
  194.   GimpLut *lut;
  195.   lut = gimp_lut_new();
  196.   intersect_lut_setup(lut, value, nchannels);
  197.   return lut;
  198. }
  199.  
  200. /* ---------------- Threshold ------------------ */
  201.  
  202. static float
  203. threshold_lut_func(double *min,
  204.          int nchannels, int channel, float value)
  205. {
  206.   /* don't change the alpha channel */
  207.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  208.     return value;
  209.   if (value < *min)
  210.     return 0.0;
  211.   return 1.0;
  212. }
  213.  
  214. void
  215. threshold_lut_setup(GimpLut *lut, double value, int nchannels)
  216. {
  217.   gimp_lut_setup_exact(lut,  (GimpLutFunc) threshold_lut_func,
  218.                (void *) &value , nchannels);
  219. }
  220.  
  221. GimpLut *
  222. threshold_lut_new(double value, int nchannels)
  223. {
  224.   GimpLut *lut;
  225.   lut = gimp_lut_new();
  226.   threshold_lut_setup(lut, value, nchannels);
  227.   return lut;
  228. }
  229.  
  230. /* ------------- levels ------------ */
  231.  
  232. typedef struct 
  233. {
  234.   double *gamma;
  235.  
  236.   int    *low_input;
  237.   int    *high_input;
  238.  
  239.   int    *low_output;
  240.   int    *high_output;
  241. } levels_struct;
  242.  
  243. static float
  244. levels_lut_func(levels_struct *data,
  245.         int nchannels, int channel, float value)
  246. {
  247.   double inten;
  248.   int j;
  249.  
  250.   if (nchannels == 1)
  251.     j = 0;
  252.   else
  253.     j = channel + 1;
  254.   inten = value;
  255.   /* For color  images this runs through the loop with j = channel +1
  256.      the first time and j = 0 the second time */
  257.   /* For bw images this runs through the loop with j = 0 the first and
  258.      only time  */
  259.   for (; j >= 0; j -= (channel + 1))
  260.   {
  261.     /* don't apply the overall curve to the alpha channel */
  262.     if (j == 0 && (nchannels == 2 || nchannels == 4)
  263.     && channel == nchannels -1)
  264.       return inten;
  265.  
  266.     /*  determine input intensity  */
  267.     if (data->high_input[j] != data->low_input[j])
  268.       inten = (double) (255.0*inten - data->low_input[j]) /
  269.     (double) (data->high_input[j] - data->low_input[j]);
  270.     else
  271.       inten = (double) (255.0*inten - data->low_input[j]);
  272.  
  273.     if (data->gamma[j] != 0.0)
  274.       {
  275.     if (inten >= 0.0)
  276.       inten =  pow ( inten, (1.0 / data->gamma[j]));
  277.     else
  278.       inten = -pow (-inten, (1.0 / data->gamma[j]));
  279.       }
  280.  
  281.   /*  determine the output intensity  */
  282.     if (data->high_output[j] >= data->low_output[j])
  283.       inten = (double) (inten * (data->high_output[j] - data->low_output[j]) +
  284.             data->low_output[j]);
  285.     else if (data->high_output[j] < data->low_output[j])
  286.       inten = (double) (data->low_output[j] - inten *
  287.             (data->low_output[j] - data->high_output[j]));
  288.  
  289.     inten /= 255.0;
  290.   }
  291.   return inten;
  292. }
  293.  
  294. void
  295. levels_lut_setup(GimpLut *lut, double *gamma, int *low_input, int *high_input,
  296.          int *low_output, int *high_output, int nchannels)
  297. {
  298.   levels_struct data;
  299.   data.gamma = gamma;
  300.   data.low_input  = low_input;
  301.   data.high_input = high_input;
  302.   data.low_output  = low_output;
  303.   data.high_output = high_output;
  304.   gimp_lut_setup(lut,  (GimpLutFunc) levels_lut_func,
  305.          (void *) &data, nchannels);
  306. }
  307.  
  308. GimpLut *
  309. levels_lut_new(double *gamma, int *low_input, int *high_input,
  310.            int *low_output, int *high_output, int nchannels)
  311. {
  312.   GimpLut *lut;
  313.   lut = gimp_lut_new();
  314.   levels_lut_setup(lut, gamma, low_input, high_input,
  315.            low_output, high_output, nchannels);
  316.   return lut;
  317. }
  318.  
  319. /* --------------- posterize ---------------- */
  320.  
  321. static float
  322. posterize_lut_func(int *ilevels,
  323.            int nchannels, int channel, float value)
  324. {
  325.   int levels;
  326.   /* don't posterize the alpha channel */
  327.   if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
  328.     return value;
  329.  
  330.   if (*ilevels < 2)
  331.     levels = 2;
  332.   else
  333.     levels = *ilevels;
  334.  
  335.   value = RINT(value * (levels - 1.0)) / (levels - 1.0);
  336.  
  337.   return value;
  338. }
  339.  
  340. void
  341. posterize_lut_setup(GimpLut *lut, int levels, int nchannels)
  342. {
  343.   gimp_lut_setup_exact(lut,  (GimpLutFunc) posterize_lut_func,
  344.                (void *) &levels , nchannels);
  345. }
  346.  
  347. GimpLut *
  348. posterize_lut_new(int levels, int nchannels)
  349. {
  350.   GimpLut *lut;
  351.   lut = gimp_lut_new();
  352.   posterize_lut_setup(lut, levels, nchannels);
  353.   return lut;
  354. }
  355.  
  356. /* --------------- equalize ------------- */
  357.  
  358. struct hist_lut_struct
  359. {
  360.   GimpHistogram *histogram;
  361.   int part[5][257];
  362. };
  363.  
  364. static float
  365. equalize_lut_func(struct hist_lut_struct *hlut, 
  366.           int nchannels, int channel, float value)
  367. {
  368.   int i = 0, j;
  369.   j = (int)(value * 255.0 + 0.5);
  370.   while (hlut->part[channel][i + 1] <= j)
  371.     i++;
  372.   return i / 255.0;
  373. }
  374.  
  375. void
  376. eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes)
  377. {
  378.   int    i, k, j;
  379.   struct hist_lut_struct hlut;
  380.   double pixels_per_value;
  381.   double desired;
  382.   double sum, dif;
  383.  
  384.   /* Find partition points */
  385.   pixels_per_value = gimp_histogram_get_count(hist, 0, 255) / 256.0;
  386.  
  387.   for (k = 0; k < bytes; k++)
  388.     {
  389.       /* First and last points in partition */
  390.       hlut.part[k][0]   = 0;
  391.       hlut.part[k][256] = 256;
  392.       
  393.       /* Find intermediate points */
  394.       j = 0;
  395.       sum = gimp_histogram_get_channel(hist, k, 0) + 
  396.         gimp_histogram_get_channel(hist, k, 1);
  397.       for (i = 1; i < 256; i++)
  398.     {
  399.       desired = i * pixels_per_value;
  400.       while (sum <= desired)
  401.       {
  402.         j++;
  403.         sum += gimp_histogram_get_channel(hist, k, j + 1);
  404.       }
  405.  
  406.       /* Nearest sum */
  407.       dif = sum - gimp_histogram_get_channel(hist, k, j);
  408.       if ((sum - desired) > (dif / 2.0))
  409.         hlut.part[k][i] = j;
  410.       else
  411.         hlut.part[k][i] = j + 1;
  412.     }
  413.     }
  414.  
  415.   gimp_lut_setup(lut, (GimpLutFunc) equalize_lut_func,
  416.          (void *) &hlut, bytes);
  417. }
  418.  
  419. GimpLut *
  420. eq_histogram_lut_new(GimpHistogram *h, int nchannels)
  421. {
  422.   GimpLut *lut;
  423.   lut = gimp_lut_new();
  424.   eq_histogram_lut_setup(lut, h, nchannels);
  425.   return lut;
  426. }
  427.